﻿// FileClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <stdio.h>

#include <Windows.h>
#include <winsock.h>
#pragma comment(lib,"Ws2_32.lib")

int main()
{
    //0.确定协议版本号 
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        printf("确定协议版本号失败%d\n", GetLastError());
        Sleep(5000);
        return -1;
    }
    printf("确定协议版本号成功\n");


    //1.创建socket
    SOCKET serverSocket = socket(AF_INET /* internetwork: UDP, TCP, etc. */, SOCK_STREAM/*字节流 二进制*/, IPPROTO_TCP/* tcp */);
    if (SOCKET_ERROR == serverSocket)
    {
        printf("创建socket失败%d\n", GetLastError());

        //8.清理协议版本信息
        WSACleanup();

        Sleep(5000);
        return -1;
    }
    printf("创建socket成功\n");


    //2..创建服务器协议地址族
    SOCKADDR_IN sadder = { 0 };
    sadder.sin_family = AF_INET/* internetwork: UDP, TCP, etc. */;      //与第一个参数一致
    sadder.sin_addr.S_un.S_addr = inet_addr("10.133.98.104");      //ip地址      作用是区分主机
    sadder.sin_port = htons(10087);  //大小端模式   一般pc机都是小端      网络服务器是unix系统，是大端       所以把整数从小端转成大端
    //我们电脑一般的端口号是65536个     并且一个应用程序绑定一个端口号    一个程序绑定了 另外一个程序就不能用了      所以使用5000以上的   10000左右的最好     数太大没什么用 数太小有可能别的程序用了   


//3.绑定
    int r = bind(serverSocket, (struct sockaddr*)&sadder, sizeof(sadder));
    if (r == -1)
    {
        printf("绑定失败%d\n", GetLastError());

        //7.关闭socket
        closesocket(serverSocket);

        //8.清理协议版本信息
        WSACleanup();

        Sleep(5000);
        return -1;
    }
    printf("绑定成功\n");


    //4.监听
    r = listen(serverSocket, 10);
    if (r == -1)
    {
        printf("监听失败%d\n", GetLastError());

        //7.关闭socket
        closesocket(serverSocket);

        //8.清理协议版本信息
        WSACleanup();

        Sleep(5000);
        return -1;
    }
    printf("监听成功\n");


    //5.接受客户端连接
    SOCKET clientSocket = accept(serverSocket, NULL, NULL);
    if (SOCKET_ERROR == clientSocket)
    {
        printf("服务器崩溃了%d\n", GetLastError());

        //7.关闭socket
        closesocket(serverSocket);

        //8.清理协议版本信息
        WSACleanup();

        Sleep(5000);
        return -1;
    }
    printf("有客户端连接上服务器了\n");


    //6.通信      客户端发数据给服务器 服务器输出到控制台
    char fileName[MAX_PATH] = { 0 };
    DWORD fileSize;

    r = recv(clientSocket, fileName, MAX_PATH - 1, NULL);
    if (r > 0) {
        printf("接收到文件名:%s\n", fileName);
    }


    r = recv(clientSocket, (char*)&fileSize, 4, NULL);
    if (4 == r) {
        printf("文件大小:%d\n", fileSize);
    }

    //创建文件
    HANDLE hFile = CreateFile(fileName, GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    char buff[1024] = { 0 };
    int cnt = 0;
    while (1)
    {
        r = recv(clientSocket, buff, 1024, NULL);
        if (r > 0)
        {
            cnt += r;   //统计接收了多少
            WriteFile(hFile, buff, r, NULL, NULL);
            if (cnt >= fileSize)
            {
                break;
            }

        }
    }


    printf("接收完毕\n");
    Sleep(5000);
    CloseHandle(hFile);





    //7.关闭socket
    closesocket(serverSocket);


    //8，清理协议版本信息
    WSACleanup();

    //注意单有server    不要直接运行

    return 0;
}
